<?php
namespace app\common\model\Goods;

use app\api\model\User\UserHobbyTagModel;
use support\Model;
use think\model\concern\SoftDelete;

class GoodsCommonModel extends Model
{
    use SoftDelete;

    protected $name = 'goods';

    protected $pk = 'id';

    protected $deleteTime = 'deletetime';

    /**
     * 状态:0=禁用,1=正常
     */
    const STATUS_OFF = 0;
    const STATUS_ON = 1;

    /**
     * 常规的获取商品列表
     * @param array|string|\Closure $where 条件
     * @param int $page 页码
     * @param int $pageSize 条数
     * @param array $sort 排序
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getGoodsList($where = [] , int $page = 1,  int $pageSize = 10 , array $sort = ['sales_volume' => 'desc'] ){
        $baseCondition = ['status' , '=' , self::STATUS_ON];
        $where[] = $baseCondition;
        $list = [];
        $field = ['*'];
        //获取数量
        $count = $this->where($where)->count();
        if(empty($count)){
            return [$count , $list];
        }
        //关联关系
        $with = [];

        $list = $this->where($where)
            ->with($with)
            ->field($field)
            ->page($page , $pageSize)
            ->order($sort)
            ->select()
            ->toArray();

        return [$list , $list];
    }


    /**
     * 获取商品列表（有用户信息则以爱好为先 ， 无用户信息则随机获取数据）
     * @param array|string|\Closure $where
     * @param int|null $userId
     * @param int $pageSize
     * @param array $sort
     * @param bool $isUseTag
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getGoodsListByHobby($where = [] , int $userId = null,  int $pageSize = 10 , array $sort = ['sales_volume' => 'desc'] , bool $isUseTag = true):array
    {
        $baseCondition = ['status' , '=' , self::STATUS_ON];
        $where[] = $baseCondition;
        $list = [];
        $goodsIdArr = [];
        $field = ['*'];

        //获取数量
        $count = $this->where($where)->count();
        if(empty($count)){
            return [$count , $list];
        }
        //关联关系
        $with = [];
        //1.获取商品表有效最大最小值
        $goodsMinId = $this->where($baseCondition)->min($this->pk);//获取最小值的商品id
        $goodsMaxId = $this->where($baseCondition)->max($this->pk);//获取最大值的商品id
        if(!empty($userId) && $isUseTag == true){
            //2. 存在用户的情况下，获取用户爱好标签，共三层
            $userHobbyTagModel = new UserHobbyTagModel();
            $getLevel = 4;
            //每个等级获取数量的比例 目前是 1 : 1 : 1 : 1
            $rateData = [ 1 , 1 , 1 , 1 , 1 ];

            for($i = 0 ; $i < $getLevel ; $i++){
                //组合数组条件
                $tmpWhere = $where;
                $hobbyTagsTmp = $userHobbyTagModel->getUserHobbyTag($userId , $i + 1 , UserHobbyTagModel::TYPE_GOODS);
                if(!empty($hobbyTagsTmp)){
                    $tmpWhere[] = $hobbyTagsTmp;
                }
                $ratePageSize = ($pageSize * $rateData[$i]) / array_sum($rateData);
                $ratePageSize = $ratePageSize < 1 ? 1 : floor($ratePageSize);
                list($tmpCount , $tmpList) = $this->getRandGoodsList($tmpWhere , $goodsMinId ,$goodsMaxId , $ratePageSize , ['id'] );
                if(!empty($tmpList)){
                    //提取主键，叠加数量
                    $goodsIdArr = array_merge($goodsIdArr , array_column($tmpList , 'id'));
                }
                unset($tmpWhere , $hobbyTagsTmp ,  $ratePageSize , $tmpCount , $tmpList );
            }
        }

        $size = count($goodsIdArr);
        if( $size < $pageSize){
            list($tmpCount , $tmpList) = $this->getRandGoodsList($where , $goodsMinId ,$goodsMaxId , $pageSize - $size , ['id'] );
            if(!empty($tmpList)){
                $goodsIdArr = array_merge($goodsIdArr , array_column($tmpList , 'id'));
            }
        }
        //3.根据主键数组去获取列表
        $list = $this->where($where)
            ->with($with)
            ->where('id' , 'IN' , $goodsIdArr)
            ->field($field)
            ->limit($pageSize)
            ->order($sort)
            ->select()
            ->toArray();

        return [$count , $list];
    }

    /**
     * @param array|\Closure $where 条件
     * @param int $minId 最小主键
     * @param int $maxId 最大主键
     * @param int $pageSize 获取数据的数量
     * @param array $field 筛选字段
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    protected function getRandGoodsList($where , int $minId , int $maxId , int $pageSize = 10 , array $field = ['*']):array
    {
        $list = [];
        $moreCount = $pageSize + 10;
        $size = 0;
        for($i = 0 ; $i < $moreCount ; $i++){
            $rand = [mt_rand($minId , $maxId) , mt_rand($minId , $maxId)];
            $minRand = min($rand);
            $maxRand = max($rand);
            $data = $this->where($where)->where( $this->pk , 'between' , [$minRand , $maxRand] )->field($field)->find();
            if(!empty($data)){
                $list[] = $data;
                $size++;
            }
            if($size >= $pageSize){
                break;
            }
            unset($data);
        }
        return [ $size , $list ];
    }

    /**
     * 关联商品详情
     * @return \think\model\relation\HasOne
     */
    public function hasOneGoodsDescribe()
    {
        return $this->hasOne(GoodsDescribeCommonModel::class , 'goods_id' , 'id');
    }



}